package com.shunda.pay.service.impl;

import com.alibaba.fastjson2.JSON;
import com.shunda.pay.dto.WxChatProfitSharingDto;
import com.shunda.pay.service.IWeChatPayCallBackService;
import com.shunda.pay.service.IWeChatPayService;
import com.shunda.pay.utils.WxPayCallbackUtil;
import com.shunda.trade.entity.TradeOrder;
import com.shunda.trade.entity.TradeWithdrawalsFlow;
import com.shunda.trade.service.TradeOrderService;
import com.shunda.trade.service.TradeWithdrawalsFlowService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 实现类
 */
@Service
public class WeChatPayCallBackServiceImpl implements IWeChatPayCallBackService {

    private final Logger log = LoggerFactory.getLogger(IWeChatPayCallBackService.class);

    private static final String SUCCESS = "SUCCESS";
    private static final String FAIL = "FAIL";
    private static final String TRADE_STATE = "trade_state";
    private static final String TRANSFER_STATE = "state";

    @Autowired
    private WxPayCallbackUtil wxChatPayCallback;
    @Autowired
    private TradeOrderService tradeOrderService;
    @Autowired
    private IWeChatPayService weChatPayService;
    @Autowired
    private TradeWithdrawalsFlowService tradeWithdrawalsFlowService;
    @Autowired
    private RSAAutoCertificateConfig rsaAutoCertificateConfig;

    /**
     * 订单支付后回调
     */
    @Override
    @Transactional
    public Map<String, String> wxOrderCallBack(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = new HashMap<>(2);
        try {
            Transaction transaction = wxChatPayCallback.wxChatCallback(request, rsaAutoCertificateConfig);
            log.info("触发支付回调逻辑 参数为 param = {}", transaction.toString());
            String orderId = transaction.getOutTradeNo(); // 内部订单ID
            String transactionId = transaction.getTransactionId(); // 微信支付订单号
            //修改订单前，建议主动请求微信查询订单是否支付成功，防止恶意post
            TradeOrder tradeOrder = tradeOrderService.queryById(Long.valueOf(orderId));
            if (tradeOrder == null) {
                log.info("内部订单号【{}】不存在", orderId);
                map.put("code", FAIL);
                map.put("message", "订单【"+ orderId +"】不存在");
                return map;
            }
            if (Integer.parseInt(tradeOrder.getPayStatus()) > 2) {
                log.info("内部订单号【{}】已支付，无需重复处理", orderId);
                map.put("code", FAIL);
                map.put("message", "订单已支付，无需重复处理");
                return map;
            }
            if (Transaction.TradeStateEnum.SUCCESS != transaction.getTradeState()) {
                log.info("内部订单号【{}】,微信支付订单号【{}】支付未成功", orderId, transactionId);
                //修改订单信息，支付状态不变
                tradeOrder.setUpdateTime(new Date());
                tradeOrder.setTransactionId(transactionId);
                tradeOrderService.update(tradeOrder);
                map.put("code", FAIL);
                map.put("message", "订单【"+ orderId +"】未支付成功");
                return map;
            }

            // 支付成功后 => 修改订单信息
            tradeOrder.setUpdateTime(new Date());
            tradeOrder.setTransactionId(transactionId);
            tradeOrder.setPayStatus("3");
            tradeOrderService.update(tradeOrder);
            // 支付成功后 => 触发分账逻辑
            WxChatProfitSharingDto sharingDto = new WxChatProfitSharingDto();
            sharingDto.setOrderId(orderId);
            sharingDto.setWxOrderId(transactionId);
            weChatPayService.createProfitSharingOrder(sharingDto);

            map.put("code", SUCCESS);
            map.put("message", "订单【"+ orderId +"】支付成功");
        } catch (Exception e) {
            log.error("支付回调失败 e = {}", e.getMessage(), e);
        }
        return map;
    }

    /**
     * 提现后回调
     */
    @Override
    public Map<String, String> transferCallBack(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = new HashMap<>(2);
        try {
            Transaction transaction = wxChatPayCallback.wxChatCallback(request, rsaAutoCertificateConfig);
            log.info("触发提现回调逻辑 参数为 param = {}", transaction.toString());
            String orderId = transaction.getOutTradeNo(); // 内部订单ID
            String transactionId = transaction.getTransactionId(); // 微信支付订单号
            //修改订单前，建议主动请求微信查询订单是否支付成功，防止恶意post
            TradeWithdrawalsFlow flow = tradeWithdrawalsFlowService.queryById(Long.valueOf(orderId));
            if (flow == null) {
                log.info("内部提现流水号【{}】不存在", orderId);
                map.put("code", FAIL);
                map.put("message", "提现流水【"+ orderId +"】不存在");
                return map;
            }
            if (Integer.parseInt(flow.getStauts()) > 2) {
                log.info("内部提现流水号【{}】到账，无需重复处理", orderId);
                map.put("code", FAIL);
                map.put("message", "提现流水已到账，无需重复处理");
                return map;
            }
            if (Transaction.TradeStateEnum.SUCCESS != transaction.getTradeState()) {
                log.info("内部提现流水号【{}】,微信提现流水号【{}】提现未成功", orderId, transactionId);
                //修改流水信息，状态不变
                flow.setUpdateDate(new Date());
                tradeWithdrawalsFlowService.update(flow);
                map.put("code", FAIL);
                map.put("message", "提现流水【"+ orderId +"】未提现成功");
                return map;
            }
            // 转账成功后，提现流水处理逻辑
            flow.setStauts("3");
            flow.setUpdateDate(new Date());
            tradeWithdrawalsFlowService.update(flow);
        } catch (Exception e) {
            log.error("转账回调失败 e = {}", e.getMessage(), e);
        }
        return map;
    }

}


